<template>
  <component
    :is="calcElTag"
    role="radiogroup"
    @keydown="handleKeydown"
    class="m-radio-group"
  >
    <slot></slot>
  </component>
</template>
<script>
import Emitter from './index';

const keyCode = Object.freeze({
  LEFT: 37,
  UP: 38,
  RIGHT: 39,
  DOWN: 40,
});
export default {
  name: 'MRadioGroup',

  componentName: 'MRadioGroup',

  mixins: [Emitter],

  inject: {
    elFormItem: {
      default: '',
    },
  },

  props: {
    // eslint-disable-next-line vue/require-default-prop
    value: {
      type: [Array, String],
    },
    size: {
      type: String,
      default: 'small',
    },
    disabled: Boolean,
    multiple: {
      type: Boolean,
      default: false,
    },
  },

  computed: {
    calcElFormItemSize() {
      return (this.elFormItem || {}).elFormItemSize;
    },
    calcElTag() {
      return (this.$vnode.data || {}).tag || 'div';
    },
    calcRadioGroupSize() {
      return this.size || this.calcElFormItemSize || (this.$ELEMENT || {}).size;
    },
    calcMode() {
      return this.multiple ? 'checkbox' : 'radio';
    },
  },
  watch: {
    // 触发form 表单事件
    value() {
      this.dispatch('ElFormItem', 'el.form.change', [this.value]);
    },
  },

  created() {
    this.$on('handleChange', (value) => {
      this.$emit('change', value);
    });
  },
  mounted() {
    // 当radioGroup没有默认选项时，第一个可以选中Tab导航
    const radios = this.$el.querySelectorAll('[type=radio]');
    const firstLabel = this.$el.querySelectorAll('[role=radio]')[0];
    if (![].some.call(radios, (radio) => radio.checked) && firstLabel) {
      firstLabel.tabIndex = 0;
    }
  },
  methods: {
    handleKeydown(e) {
      // 左右上下按键 可以在radio组内切换不同选项
      const { target } = e;
      const className =
        target.nodeName === 'INPUT'
          ? `[type=${this.calcMode}]`
          : `[role=${this.calcMode}]`;
      const radios = this.$el.querySelectorAll(className);
      const { length } = radios;
      const index = [].indexOf.call(radios, target);
      const roleRadios = this.$el.querySelectorAll(`[role=${this.calcMode}]`);
      switch (e.keyCode) {
        case keyCode.LEFT:
        case keyCode.UP:
          e.stopPropagation();
          e.preventDefault();
          if (index === 0) {
            roleRadios[length - 1].click();
            roleRadios[length - 1].focus();
          } else {
            roleRadios[index - 1].click();
            roleRadios[index - 1].focus();
          }
          break;
        case keyCode.RIGHT:
        case keyCode.DOWN:
          if (index === length - 1) {
            e.stopPropagation();
            e.preventDefault();
            roleRadios[0].click();
            roleRadios[0].focus();
          } else {
            roleRadios[index + 1].click();
            roleRadios[index + 1].focus();
          }
          break;
        default:
          break;
      }
    },
  },
};
</script>
<style scoped lang="less">
.m-radio-group {
  font-size: 0;
}
</style>
